Security News
JSR Working Group Kicks Off with Ambitious Roadmap andΒ Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
fast-check
Advanced tools
fast-check is a property-based testing library for JavaScript and TypeScript. It allows developers to define properties that should hold true for a wide range of inputs, and then automatically generates test cases to verify those properties. This helps in identifying edge cases and ensuring the robustness of the code.
Property-based Testing
This feature allows you to define properties that should hold true for a wide range of inputs. In this example, the property being tested is the commutativity of addition.
const fc = require('fast-check');
fc.assert(
fc.property(fc.integer(), fc.integer(), (a, b) => {
return a + b === b + a;
})
);
Custom Arbitraries
Custom arbitraries allow you to define complex data structures for your tests. In this example, a custom arbitrary is created that generates objects with a number and a string.
const fc = require('fast-check');
const myArbitrary = fc.tuple(fc.integer(), fc.string()).map(([num, str]) => ({ num, str }));
fc.assert(
fc.property(myArbitrary, ({ num, str }) => {
return typeof num === 'number' && typeof str === 'string';
})
);
Shrinkable Values
Shrinkable values help in minimizing the size of failing test cases to make debugging easier. In this example, if the property fails, fast-check will try to find the smallest array that causes the failure.
const fc = require('fast-check');
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
return arr.length < 100;
}),
{ verbose: true }
);
jsverify is another property-based testing library for JavaScript. It offers similar functionality to fast-check, such as defining properties and generating test cases. However, fast-check is generally considered to have a more modern API and better TypeScript support.
testcheck is a property-based testing library inspired by QuickCheck. It provides similar capabilities for generating test cases and defining properties. Compared to fast-check, testcheck is less actively maintained and has fewer features.
Hypothesis is a property-based testing library for Python, but it has inspired several JavaScript libraries, including fast-check. While not a direct competitor, it offers similar concepts and is often used as a reference for property-based testing.
Property based testing framework for JavaScript/TypeScript
Hands-on tutorial and definition of Property Based Testing: π see tutorial. Or directly try it online on our pre-configured CodeSandbox.
Property based testing frameworks check the truthfulness of properties. A property is a statement like: for all (x, y, ...) such that precondition(x, y, ...) holds predicate(x, y, ...) is true.
Install the module with: yarn add fast-check --dev
or npm install fast-check --save-dev
Example of integration in mocha:
const fc = require('fast-check');
// Code under test
const contains = (text, pattern) => text.indexOf(pattern) >= 0;
// Properties
describe('properties', () => {
// string text always contains itself
it('should always contain itself', () => {
fc.assert(fc.property(fc.string(), text => contains(text, text)));
});
// string a + b + c always contains b, whatever the values of a, b and c
it('should always contain its substrings', () => {
fc.assert(fc.property(fc.string(), fc.string(), fc.string(), (a,b,c) => {
// Alternatively: no return statement and direct usage of expect or assert
return contains(a+b+c, b);
}));
});
});
In case of failure, the test raises a red flag. Its output should help you to diagnose what went wrong in your implementation. Example with a failing implementation of contain:
1) should always contain its substrings
Error: Property failed after 1 tests (seed: 1527422598337, path: 0:0): ["","",""]
Shrunk 1 time(s)
Got error: Property failed by returning false
Hint: Enable verbose mode in order to have the list of all failing values encountered during the run
Integration with other test frameworks: ava, jasmine, jest, mocha and tape.
More examples: simple examples, fuzzing and against various algorithms.
Useful documentations:
fast-check has initially been designed in an attempt to cope with limitations I encountered while using other property based testing frameworks designed for JavaScript:
map
method to derive existing arbitraries while keeping shrink [more] - some frameworks ask the user to provide both a->b and b->a mappings in order to keep a shrinkerchain
[more] - able to bind the output of an arbitrary as input of another one while keeping the shrink workingfc.pre(...)
[more] - filtering invalid entries can be done directly inside the check function if neededfc.oneof
[more] - surprisingly some frameworks don'tFor more details, refer to the documentation in the links above.
Here are the minimal requirements to use fast-check properly without any polyfills:
fast-check | node | ECMAScript version | TypeScript (optional) |
---|---|---|---|
2.x | β₯8(1) | ES2017 | β₯3.2 |
1.x | β₯0.12(1) | ES3 | β₯3.0 |
(1) Except for features that cannot be polyfilled - such as bigint
-related ones - all the capabilities of fast-check should be usable given you use at least the minimal recommended version of node associated to your major of fast-check.
ReScript bindings
Bindings to use fast-check in ReScript are available in package rescript-fast-check. They are maintained by @TheSpyder as an external project.
fast-check has been able to find some unexpected behaviour among famous npm packages. Here are some of the errors detected using fast-check:
Issue detected: toStrictEqual
fails to distinguish 0 from 5e-324 [more]
Code example: expect(0).toStrictEqual(5e-324)
succeeds
Issue detected: enabling !!int: binary
style when dumping negative integers produces invalid content [more]
Code example: yaml.dump({toto: -10}, {styles:{'!!int':'binary'}})
produces toto: 0b-1010
not toto: -0b1010
Issue detected: enabling the bracket
setting when exporting arrays containing null values produces an invalid output for the parser [more]
Code example:
m.stringify({bar: ['a', null, 'b']}, {arrayFormat: 'bracket'}) //=> "bar[]=a&bar&bar[]=b"
m.parse('bar[]=a&bar&bar[]=b', {arrayFormat: 'bracket'}) //=> {bar: [null, 'b']}
MORE: Issues detected thanks to fast-check
Code Contributors
This project would not be the same without them π - Become one of them
Backers
Thank you to all our backers! π [Become a backer] and help us sustain our community.
Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
FAQs
Property based testing framework for JavaScript (like QuickCheck)
The npm package fast-check receives a total of 1,208,846 weekly downloads. As such, fast-check popularity was classified as popular.
We found that fast-check demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.